package com.threeti.mecool.core.util;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.security.MessageDigest;
import java.util.Arrays;

public final class AESUtil {
    private static final String code = "threeti";
    private static final int saltSize = 5;
    private static AESUtil instance;
    private Cipher enCipher;
    private Cipher deCipher;

    static {
        try {
            byte[] key = code.getBytes("UTF-8");
            MessageDigest sha = MessageDigest.getInstance("SHA-1");
            key = sha.digest(key);
            key = Arrays.copyOf(key, 16);
            SecretKeySpec sk = new SecretKeySpec(key, "AES");
            instance = new AESUtil(sk);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static String encryptString(String s) {
        if (s == null) {
            throw new RuntimeException("encrypt string shall not be null");
        }
        return instance.encrypt(s);
    }

    public static String decryptString(String s) {
        return instance.decrypt(s);
    }

    public static String encryptDynamicString(String s) {
        if (s == null) {
            throw new RuntimeException("encrypt string shall not be null");
        }
        String salt = String.valueOf(System.nanoTime());
        salt = salt.substring(salt.length() - saltSize);
        return instance.encrypt(salt + s);
    }

    public static String decryptDynamicStr(String s) {
        String ret = instance.decrypt(s);
        if (ret != null) {
            try {
                ret = ret.substring(saltSize);
            } catch (Exception e) {
                ret = null;
            }
        }
        return ret;
    }

    private AESUtil(SecretKey key) {
        try {
            enCipher = Cipher.getInstance("AES");
            deCipher = Cipher.getInstance("AES");
            enCipher.init(Cipher.ENCRYPT_MODE, key);
            deCipher.init(Cipher.DECRYPT_MODE, key);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public String encrypt(String str) {
        try {
            byte[] utf8 = str.getBytes("UTF-8");
            byte[] enc = enCipher.doFinal(utf8);
            return ByteUtil.byte2ascii(enc);
        } catch (Exception e) {
            return null;
        }
    }

    public String decrypt(String str) {
        try {
            byte[] dec = ByteUtil.ascii2byte(str);
            byte[] utf8 = deCipher.doFinal(dec);
            return new String(utf8, "UTF8");
        } catch (Exception e) {
            return null;
        }
    }

}
